﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RPGSoundmixerGUI.Forms.Interface;
using RPGSoundmixerGUI.Forms;
using RPGSoundmixerGUI.Text;
using RPGSoundmixerGUI.Exceptions;
using System.Diagnostics;
using RPGSoundmixerGUI.DataHandlerReference;
using Foundation;
using RPGSoundmixerGUI.Forms.UserControls;

namespace RPGSoundmixerGUI.Controller {
    public class MainController {

        

        /// <summary>
        /// Aktuell geladene SoundSuite
        /// </summary>
        private Foundation.SoundSuite currentSoundSuite; 


        /// <summary>
        /// Property für die Injection eines DataHandlers zu Testzwecken
        /// </summary>
        public IDataHandler DataHandler {
            set {
                this.dataHandler = value;
            }
        }

        #region Injection Methoden für Unit Tests

        [Conditional("DEBUG")]
        public void SetTabObjectList (Dictionary<Guid, TabView> tabs){
            this.tabs = tabs; 
        }

        [Conditional("DEBUG")]
        public void SetCurrentSoundSuite(Foundation.SoundSuite suite) {
            this.currentSoundSuite = suite; 
        }

        #endregion

        // todo na Mit Dependecy Injection angeben
        /// <summary>
        /// Die Referenz auf den DataHandler Service
        /// </summary>
        private IDataHandler dataHandler = new DataHandlerClient();

        /// <summary>
        /// Die Refernz auf das MainForm
        /// </summary>
        private IMainForm mainForm;

        /// <summary>
        /// Collection für die anzuzeigenden Tabs
        /// </summary>
        private Dictionary<Guid, TabView> tabs;
        
        /// <summary>
        /// Leerer Konstruktor
        /// </summary>
        public MainController() {
            tabs = new Dictionary<Guid, TabView>(); 
        }

        /// <summary>
        /// Konstruktor, welcher einen MainController entgegen nimmt.
        /// </summary>
        /// <param name="view"></param>
        public MainController(Forms.Interface.IMainForm view)
            : this() {
            this.mainForm = view;
            this.mainForm.OnDatabaseParameterChanged += new Forms.Events.PropertyChangedHandler(mainForm_OnDatabaseParameterChanged);
            this.mainForm.OnTreeItemSelected += new Forms.Events.TreeItemSelectedHandler(mainForm_OnTreeItemSelected);
        }

        void mainForm_OnTreeItemSelected(object sender, Forms.Events.TreeItemSelectedEventArgs args) {
            Guid objectID = Guid.Empty;

            if (args.SelectedItem.GetType().Equals(typeof(Foundation.SoundSuite))) {
                objectID = ((Foundation.SoundSuite)args.SelectedItem).Id;
            }
            else if (args.SelectedItem.GetType().Equals(typeof(Foundation.EffectGroup))) {
                objectID = ((Foundation.EffectGroup)args.SelectedItem).ID;
            }
            else if (args.SelectedItem.GetType().Equals(typeof(Foundation.Effect))) {
                objectID = ((Foundation.Effect)args.SelectedItem).Id;
            }


            if (this.tabs.ContainsKey(objectID)) {
                this.mainForm.ShowTabInFront(tabs[objectID]);
            }
            else {                
                this.mainForm.AddTab(GetTabViewByItem(args.SelectedItem));
            }
        }

        /// <summary>
        /// Gibt einen TabView anhand eines Objektes zurück
        /// </summary>
        /// <param name="item">Item, welches angezeigt werden soll</param>
        /// <returns></returns>
        private static TabView GetTabViewByItem(object item) {
            if (item.GetType().Equals(typeof(Foundation.SoundSuite))) {
                return new SoundSuiteTab(item as Foundation.SoundSuite);
            }
            else if (item.GetType().Equals(typeof(Foundation.EffectGroup))) {
                return new EffectGroupTab(item as Foundation.EffectGroup);
            }
            else if (item.GetType().Equals(typeof(Foundation.Effect))) {
                return new EffectTab(item as Foundation.Effect);
            }
            else {
                return null;
            }
        }


        /// <summary>
        /// EventHandler, welcher den Event behandelt, welcher die Datenbank Informationen ändern will
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void mainForm_OnDatabaseParameterChanged(object sender, Forms.Events.PropertyChangedEventArgs args) {
            if (string.IsNullOrEmpty(args.DataBasePath)) {
                throw new DataBaseException(TextDispenser.GetText(100001), null, 100001);
            }
            dataHandler.SetConnectionString(string.Format("Data Source={0};Version=3;", args.DataBasePath), RPGSoundmixerGUI.DataHandlerReference.DataBaseType.SQLite); 
        }

        
        
    }
}
